package com.jrx.anytxn.accounting.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.jrx.anytxn.accounting.constant.AccountBizConstant;
import com.jrx.anytxn.accounting.dto.GaVoucherInfoRep;
import com.jrx.anytxn.accounting.dto.VoucherInfoRes;
import com.jrx.anytxn.accounting.entity.GaVoucherInfo;
import com.jrx.anytxn.accounting.mapper.ext.ExtVoucherInfoMapper;
import com.jrx.anytxn.accounting.service.IVoucherInfoService;
import com.jrx.anytxn.common.data.TxnRespCode;
import com.jrx.anytxn.common.exception.TxnBizException;
import com.jrx.anytxn.common.exception.TxnException;
import com.jrx.anytxn.common.uitl.BeanMapping;
import com.jrx.anytxn.common.uitl.DateUtils;
import com.jrx.anytxn.common.uitl.SeqUtils;
import com.jrx.anytxn.i18n.response.TxnPage;
import com.jrx.anytxn.number.exception.SegmentException;
import com.jrx.anytxn.number.service.ISegmentService;
import com.jrx.anytxn.param.constant.Constant;
import com.jrx.anytxn.param.constant.ErrorMsgConstant;
import com.jrx.anytxn.param.dto.system.SystemParameterRes;
import com.jrx.anytxn.param.entity.PrOrganizationTable;
import com.jrx.anytxn.param.entity.TlManualVoucherLog;
import com.jrx.anytxn.param.mapper.base.TlManualVoucherLogMapper;
import com.jrx.anytxn.param.service.system.IOrganizationTableService;
import com.jrx.anytxn.param.service.system.ISystemParameterService;
import com.jrx.anytxn.transaction.constant.TransBizConstant;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.math.BigDecimal;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @ClassName VoucherInfoServiceImpl
 * @Description: 传票流水表service实现
 * @Author yf
 * @Date 2019/9/9 0009
 * @Version V1.0
 **/
@Service
public class VoucherInfoServiceImpl implements IVoucherInfoService {

    private static final Logger logger = LoggerFactory.getLogger(VoucherInfoServiceImpl.class);

    @Resource
    private ExtVoucherInfoMapper extVoucherInfoMapper;
    @Autowired
    private ISegmentService segmentService;
    @Resource
    private TlManualVoucherLogMapper tlManualVoucherLogMapper;
    @Autowired
    private ISystemParameterService systemParameterService;
    @Autowired
    private IOrganizationTableService organizationTableService;

    @Override
    public TxnPage<VoucherInfoRes> getVoucherInfoByPage(Integer pageNum, Integer pageSize, String tenantId, String startDate, String endDate, String loanId, String customerId, String channel) throws TxnBizException {
        Page<GaVoucherInfo> page = PageHelper.startPage(pageNum, pageSize);
        List<GaVoucherInfo> voucherInfoResList = extVoucherInfoMapper.selectVoucherInfoByTenId(tenantId, startDate, endDate, loanId, customerId, channel);
        if (voucherInfoResList.isEmpty()) {
            logger.error("查询的传票流水表列表为空");
            throw new TxnBizException(TxnRespCode.SUCCESS.getCode(), "分页查询传票流水表没有数据");
        }
        List<VoucherInfoRes> res = BeanMapping.copyList(voucherInfoResList, VoucherInfoRes.class);
        return new TxnPage<>(pageNum, pageSize, page.getTotal(), res);
    }

    @Override
    public VoucherInfoRes getVoucherInfoByIdAndTenIdAndCusId(Long id, String tenantId, String customerId) throws TxnBizException {
        if (id == null && StringUtils.isBlank(tenantId)) {
            logger.error("传票流水表主键ID或租户ID为空");
            throw new TxnBizException(TxnRespCode.NOT_EMPTY.getMsg());
        }
        GaVoucherInfo voucherInfo = extVoucherInfoMapper.selectByIdAndTenIdAndCusId(id, tenantId, customerId);
        if (null == voucherInfo) {
            logger.error("根据主键[{}]查询的传票流水信息为空", id);
            throw new TxnBizException(TxnRespCode.NO_DATA.getMsg());
        }
        return BeanMapping.copy(voucherInfo, VoucherInfoRes.class);
    }


    @Override
    public TxnPage<VoucherInfoRes> getAllPageBySubjectId(String subjectId, String tenantId, Integer pageNum, Integer pageSize) throws TxnBizException {
        Page<GaVoucherInfo> page = PageHelper.startPage(pageNum, pageSize);
        List<GaVoucherInfo> voucherInfoResList = extVoucherInfoMapper.selectVoucherInfoBySubjectIdAndTenantId(subjectId, tenantId);
        if (voucherInfoResList.isEmpty()) {
            logger.error("查询的传票流水表列表为空");
            throw new TxnBizException(TxnRespCode.SUCCESS.getCode(), "分页查询传票流水表没有数据");
        }
        List<VoucherInfoRes> res = BeanMapping.copyList(voucherInfoResList, VoucherInfoRes.class);
        return new TxnPage<>(pageNum, pageSize, page.getTotal(), res);
    }

    @Override
    public TxnPage<VoucherInfoRes> createVoucherInfoByList(List<GaVoucherInfoRep> gaVoucherInfoList, String tenantId, String userName) throws TxnException {
        logger.info("接收到参数：[{}]", gaVoucherInfoList);
        String fiowNo = SeqUtils.getSNByLength(TransBizConstant.GL_FLOW_NO_RANDOM);

        List<GaVoucherInfo> infos = new ArrayList<>(gaVoucherInfoList.size());
        int seqNumber = 0;
        for (GaVoucherInfoRep ga : gaVoucherInfoList) {
            GaVoucherInfo gaVoucherInfo = new GaVoucherInfo();
            try {
                gaVoucherInfo.setId(segmentService.getId(AccountBizConstant.TABLE_VOUCHERINFO));
            } catch (SegmentException e) {
                logger.error("主键生成错误", e);
                throw new TxnException(ErrorMsgConstant.ERROR_ID);
            }
            gaVoucherInfo.setProductId("0");
            gaVoucherInfo.setLoanClassify("0");
            gaVoucherInfo.setAmount(ga.getAmount());
            gaVoucherInfo.setChannel(ga.getChannel());
            gaVoucherInfo.setDescription(ga.getDescription());
            gaVoucherInfo.setOrganizationId(ga.getOrganizationId());
            gaVoucherInfo.setSign(ga.getSign());
            gaVoucherInfo.setSubjectId(ga.getSubjectId());
            gaVoucherInfo.setFlowno(fiowNo);
            gaVoucherInfo.setTenantId(tenantId);
            gaVoucherInfo.setBusinessDate(ga.getBusinessDate());
            gaVoucherInfo.setLoanId("0");
            gaVoucherInfo.setSeq(seqNumber);
            gaVoucherInfo.setCustomerId("0");
            gaVoucherInfo.setAccountId("0");
            gaVoucherInfo.setTxnCode("0");
            gaVoucherInfo.setCurrency(AccountBizConstant.CURRENCY);
            gaVoucherInfo.setVoucherType("G");
            gaVoucherInfo.setSrc("A");
            gaVoucherInfo.setCategory("0");
            gaVoucherInfo.setUpdateBy(userName);
            gaVoucherInfo.setRecordVersionNumber(Constant.VERSION_NUMBER);
            gaVoucherInfo.setInvestorId(TransBizConstant.DEFAULT_INNER_INVESTOR_ID);
            seqNumber++;
            infos.add(gaVoucherInfo);
        }
        //写入传票流水表
        extVoucherInfoMapper.batchInsert(infos);
        //写入手动传票流水表
        TlManualVoucherLog tlManualVoucherLog = new TlManualVoucherLog();
        try {
            tlManualVoucherLog.setId(segmentService.getId(AccountBizConstant.TABLE_TL_MANUAL_VOUCHER_LOG));
        } catch (SegmentException e) {
            logger.error("主键生成错误", e);
            throw new TxnException(ErrorMsgConstant.ERROR_ID);
        }
        tlManualVoucherLog.setTenantId(tenantId);
        tlManualVoucherLog.setOrganizationId(gaVoucherInfoList.get(0).getOrganizationId());
        tlManualVoucherLog.setBusinessDate(gaVoucherInfoList.get(0).getBusinessDate());
        tlManualVoucherLog.setFlowno(fiowNo);
        tlManualVoucherLog.setUpdateBy(userName);
        tlManualVoucherLog.setRecordVersionNumber(Constant.VERSION_NUMBER);

        tlManualVoucherLogMapper.insertSelective(tlManualVoucherLog);

        List<VoucherInfoRes> res = BeanMapping.copyList(infos, VoucherInfoRes.class);
        return new TxnPage<>(1, infos.size(), infos.size(), res);
    }

    @Override
    public String getVoucherFileMeaage(GaVoucherInfo info) throws TxnException {
        //根据机构号获取
        SystemParameterRes res = systemParameterService.findByParamCode(AccountBizConstant.PARAM_CODE, info.getTenantId());

        StringBuffer sb = new StringBuffer();
        sb.append((res.getParamValue() == null ? "" : res.getParamValue()) + AccountBizConstant.separator);
        String busDate = info.getBusinessDate() == null ? "" : DateUtils.format(info.getBusinessDate());
        sb.append(busDate + AccountBizConstant.separator);
        sb.append((info.getFlowno() == null ? "" : info.getFlowno()) + AccountBizConstant.separator);
        sb.append((info.getSeq() == null ? "0" : info.getSeq()) + AccountBizConstant.separator);
        sb.append((info.getSubjectId() == null ? "" : info.getSubjectId()) + AccountBizConstant.separator);
        sb.append((info.getSign() == null ? "" : info.getSign()) + AccountBizConstant.separator);
        sb.append((info.getAmount() == null ? "0.00" : info.getAmount().setScale(2, BigDecimal.ROUND_HALF_UP)) + AccountBizConstant.separator);
        sb.append((info.getTxnCode() == null ? "" : info.getTxnCode()) + AccountBizConstant.separator);
        sb.append((info.getLoanId() == null ? "" : info.getLoanId()) + AccountBizConstant.separator);
        sb.append(info.getChannel() == null ? "" : info.getChannel());

        return sb.toString();
    }

    @Override
    public void generatingFile(List<String> messageList, String reportingPath, String fileName, String fileType) {
        PrOrganizationTable org = organizationTableService.findByOrgIdForBatch(TransBizConstant.DEFAULT_ORG_ID);
        String today = DateUtils.format(org.getToday(), "yyyyMMdd");

        String filePath = reportingPath + org.getTenantId() + File.separator + today + File.separator;

        String collectionFileName = fileType + "_" + today + "_" + fileName + ".txt";

        Path reportingFile = Paths.get(filePath + collectionFileName);

        Integer i = 0;
        try (FileWriter bfw = new FileWriter(reportingFile.toFile(), true);
             BufferedWriter writer = new BufferedWriter(bfw, 10240)) {
            if (reportingFile.toFile().length() != 0) {
                writer.write("\r\n");
            }
            for (String message : messageList) {
                i++;
                if (i == messageList.size()) {
                    writer.write(message);
                } else {
                    writer.write(message + "\r\n");
                }
            }
            writer.flush();
        } catch (IOException e) {
            logger.error("传票文件生成异常，异常信息：", e);
            throw new RuntimeException(e);
        }
    }

    @Override
    public void deleteByDateAndInvestorId(Date businessDate, String invesrorId) {
        if ("0".equals(invesrorId)) {
            //删除非联合贷传票
            extVoucherInfoMapper.deleteByDateAndInvestorId(businessDate, invesrorId);
        } else {
            //删除联合贷传票
            extVoucherInfoMapper.deleteByDateAndNotInvestorId(businessDate, "0");
        }
    }
}
